﻿using System;
using System.Collections.Generic;
using Audio;
using UnityEngine;
using UnityEngine.Assertions;
using Utils;

namespace Combat
{
    public class WeaponSwitch : MonoBehaviour
    {
        public event Action<int, Weapon> WeaponUnlocked;
        public event Action<int, Weapon> WeaponSwitched;
        
        [SerializeField] private Weapon[] weapons;
        [SerializeField] private AudioClip switchSound;
        
        private Shooter _shooter;

        private readonly HashSet<int> _unlockedWeapons = new() { 0 };
        
        private Timer _coolingTimer;

        private int _currentWeaponIndex = 0;


        private void Awake()
        {
            _shooter = GetComponent<Shooter>();
            
            _coolingTimer = new Timer(0.1f);
        }

        private void Update()
        {
            _coolingTimer.Tick();
        }

        public void SwitchWeapon(int index)
        {
            if (!_unlockedWeapons.Contains(index))
            {
                return;
            }
            Assert.IsTrue(index >= 0 && index < weapons.Length, "Weapon index is out of range.");
            if (_shooter.CurrentWeapon == weapons[index])
            {
                return;
            }

            if (_coolingTimer.IsActive)
            {
                return;
            }
            
            _coolingTimer.Reset();
            _shooter.SetWeapon(weapons[index]);
            AudioPlayer.Instance.PlaySound(switchSound);
            WeaponSwitched?.Invoke(index, weapons[index]);
            _currentWeaponIndex = index;
        }

        public void NextWeapon()
        {
            int nextIndex = (_currentWeaponIndex + 1) % _unlockedWeapons.Count;
            
            SwitchWeapon(nextIndex);
        }

        public void PreviousWeapon()
        {
            int previousIndex = _currentWeaponIndex - 1;
            if (previousIndex < 0)
            {
                previousIndex = _unlockedWeapons.Count - 1;
            }
            
            SwitchWeapon(previousIndex);
        }

        public void UnlockWeapon(int index)
        {
            if (_unlockedWeapons.Contains(index))
            {
                return;
            }
            
            _unlockedWeapons.Add(index);
            WeaponUnlocked?.Invoke(index, weapons[index]);
            
            SwitchWeapon(index);
        }
    }
}